#include "advancingFront2D.h"

AdvancingFront2D::AdvancingFront2D() : Methods(){
}

AdvancingFront2D::~AdvancingFront2D(){
}

std::vector<Face *> AdvancingFront2D::calculate(Object *_obj, Face *_f){
    fixEdges(_obj, _f);
    return triangulate(_obj, _f);
}

std::vector<Face *> AdvancingFront2D::triangulate(Object *_obj, Face *_f){
    std::cout <<"------------------- Avanço de fronteira 2D "<<std::endl;

    //criando o vetor de arestas, de todas as arestas da face.
    std::vector<Edge *> edges;
    std::vector<bool> edgesSignals;
    std::vector<Edge *> constraints;
    Edge *edge = _f->getEdge();
    bool edgeSignal = _f->getEdgeSignal();
    do{
        edges.push_back(edge);
        edgesSignals.push_back(edgeSignal);
        constraints.push_back(edge);
        if(edgeSignal){
            edgeSignal = edge->getNextClockwiseSignal();
            edge = edge->getNextClockwise();
        }else{
            edgeSignal = edge->getNextCounterClockwiseSignal();
            edge = edge->getNextCounterClockwise();
        }
    }while (edge != _f->getEdge());


    std::vector<Face *> result;

    std::vector<Vertex *> vertices;
    bool notOK, edge1Signal, edge2Signal;
    int size, chosenVertexI;
    double minCosAlpha = 2; //é o minimo cos, porque queremos o max angulo
    double currentCosAlpha;
    Vertex *currentVertex, *vertex;
    Edge *constraint, *edge1, *edge2;
    Face *newFace;

    while(!edges.empty()){
        edge = edges.front();
        edges.erase(edges.begin());

        edgeSignal = edgesSignals.front();
        edgesSignals.erase(edgesSignals.begin());

//        std::cout <<"\n\n\nolhando a aresta: "  << edge->getID() << " de sinal " << edgeSignal<<std::endl;

        vertices = _f->getVerticesInThePlan();
        notOK = true;
        //busca o melhor ponto
        while(notOK){
            size = vertices.size();
            minCosAlpha = 2;
            chosenVertexI = -1;
            //pegar o que faz o maior angulo com a aresta
            for(int i = 0; i < size; i++){
                currentVertex = vertices.at(i);
//                std::cout << "\n\n\ncurrent vertex: " << currentVertex->getID() <<std::endl;
                //dispensando de olhar o começo e o fim dauqla aresta
                if( (currentVertex == edge->getStart()) || (currentVertex == edge->getEnd()) ) continue;

                //ignorando os paralelos
                if( isParallel(*edge, Edge(-1, edge->getStart(), currentVertex)) ) continue;

                //testando se o vertice está no lugar certo
                if( edgeSignal ){
                    Point ni = ((edge->getEnd()->getPoint() - edge->getStart()->getPoint()).crossProduct(currentVertex->getPoint() - edge->getStart()->getPoint())).normalization();
                    Point nf = _f->normal();
                    if(cosAlpha(ni, nf) <= 0.0) continue;
                }else{
                    Point ni = ((edge->getStart()->getPoint() - edge->getEnd()->getPoint()).crossProduct(currentVertex->getPoint() - edge->getEnd()->getPoint())).normalization();
                    Point nf = _f->normal();
                    if(cosAlpha(ni, nf) <= 0.0) continue;
                }

                currentCosAlpha = cosAlpha((edge->getStart()->getPoint() - currentVertex->getPoint()).normalization(), (edge->getEnd()->getPoint() - currentVertex->getPoint()).normalization());

                if (currentCosAlpha < minCosAlpha){
                    minCosAlpha = currentCosAlpha;
                    chosenVertexI = i;
                }
            }

            //***APAGR ISSO!
            if(chosenVertexI == -1){
                std::cout <<"Deu problema! não achou I!" <<std::endl;
            }

            //testar contra as restições
            vertex = vertices.at(chosenVertexI);
//            std::cout << "\n\nTentativa com vertice : " << vertex->getID() <<std::endl;
//            std::cout << "Testando contra as "<< constraints.size()  << " restrições." <<std::endl;

            size = constraints.size();
            notOK = false;
            for(int i = 0; i < size; i++){
                constraint = constraints.at(i);
//                std::cout << "\trestição "<< i << " \taresta " <<constraint ->getID()<< std::endl;
                //em relação ao vertice inicial da aresta
                if(haveIntersection(*constraint, Edge(-1, edge->getStart(), vertex))){
//                    std::cout <<"Se cruzam!" <<std::endl;
                    vertices.erase(vertices.begin() + chosenVertexI);
                    notOK = true;
                    break;
                }
                //em relação ao vertice final da aresta
                if(haveIntersection(*constraint, Edge(-1, edge->getEnd(), vertex))){
//                    std::cout <<"Se cruzam!" <<std::endl;
                    vertices.erase(vertices.begin() + chosenVertexI);
                    notOK = true;
                    break;
                }
            }
            //se tiver tudo ok, coloca o bool como falso

            //***APAGR ISSO!
            if(vertices.empty()){
                std::cout <<"Deu problema, nao achou nenhum!" <<std::endl;
            }

        }

        //faz uma nova face
        newFace = new Face(faceID++, _obj, edge, edgeSignal, true);
        result.push_back(newFace);

//        std::cout <<"Achou vertice : " << vertex->getID() << "\tFace " << newFace->getID() << " criada!!" <<std::endl;

        //faz-se as novas arestas
        //incluir as arestas como restrições
        if(edgeSignal){
            edge1 = new Edge(edgeID++, edge->getEnd(), vertex);
            edge1Signal = _obj->addEdge(&edge1);
            if(edge1Signal){
                vertices.clear();
                vertices.push_back(edge->getEnd());
                vertices.push_back(vertex);
                vertices.push_back(edge->getStart());
                newFace->setVerticesInThePlan(vertices);
            }else{
                vertices.clear();
                vertices.push_back(vertex);
                vertices.push_back(edge->getEnd());
                vertices.push_back(edge->getStart());
                newFace->setVerticesInThePlan(vertices);
            }
            if(edge1->getID() != edgeID - 1){
//                std::cout <<"!!achou uma aresta que ja existia " << edge1->getID() <<std::endl;
                edgeID = edgeID - 1;
            }

            edge2 = new Edge(edgeID++, vertex, edge->getStart());
            edge2Signal = _obj->addEdge(&edge2);
            if(edge2->getID() != edgeID - 1){
//                std::cout <<"!!achou uma aresta que ja existia " << edge2->getID() <<std::endl;
                edgeID = edgeID - 1;
            }
        }else{
            edge1 = new Edge(edgeID++, edge->getStart(), vertex);
            edge1Signal = _obj->addEdge(&edge1);
            if(edge1Signal){
                vertices.clear();
                vertices.push_back(edge->getStart());
                vertices.push_back(vertex);
                vertices.push_back(edge->getEnd());
                newFace->setVerticesInThePlan(vertices);
            }else{
                vertices.clear();
                vertices.push_back(vertex);
                vertices.push_back(edge->getStart());
                vertices.push_back(edge->getEnd());
                newFace->setVerticesInThePlan(vertices);
            }
            if(edge1->getID() != edgeID - 1){
//                std::cout <<"!!achou uma aresta que ja existia " << edge1->getID()<<std::endl;
                edgeID = edgeID - 1;
            }

            edge2 = new Edge(edgeID++, vertex, edge->getEnd());
            edge2Signal = _obj->addEdge(&edge2);
            if(edge2->getID() != edgeID - 1){
//                std::cout <<"!!achou uma aresta que ja existia " <<edge2->getID()<<std::endl;
                edgeID = edgeID - 1;
            }
        }

        if(!edge1->isBoundary()){
            //caso a aresta não tenha sida achada ate então
            //colocar nas listas
            edge1->setIsBoundary(true);
            constraints.push_back(edge1);
            edges.push_back(edge1);
            edgesSignals.push_back(!edge1Signal);//tem que ser o oposto para ficar pronto para a proxima face
        }else{
            //caso contrario, remove-la da lista
            for(unsigned int i = 0; i < edges.size(); i++){
                if(edges.at(i) == edge1){
                    edges.erase(edges.begin() + i);
                    edgesSignals.erase(edgesSignals.begin() + i);
                    break;
                }
            }
        }

        if(!edge2->isBoundary()){
            //caso a aresta não tenha sida achada ate então
            //colocar nas listas
            edge2->setIsBoundary(true);
            constraints.push_back(edge2);
            edges.push_back(edge2);
            edgesSignals.push_back(!edge2Signal);//tem que ser o oposto para ficar pronto para a proxima face
        }else{
            //caso contrario, remove-la da lista
            for(unsigned int i = 0; i < edges.size(); i++){
                if(edges.at(i) == edge2){
                    edges.erase(edges.begin() + i);
                    edgesSignals.erase(edgesSignals.begin() + i);
                    break;
                }
            }
        }



        //faz as conexões da winged-edge
        //coloca as arestas, vertices e face como sendo do fecho
        vertex->setIsBoundary(true);
        vertex->setEdge(edge2, edge2Signal);

        if(edge1Signal){
            edge1->setClockwise(newFace);

            edge1->setPreviousClockwise(edge, edgeSignal);
            edge1->setNextClockwise(edge2, edge2Signal);
        }else{
            edge1->setCounterClockwise(newFace);

            edge1->setPreviousCounterClockwise(edge, edgeSignal);
            edge1->setNextCounterClockwise(edge2, edge2Signal);
        }

        if(edge2Signal){
            edge2->setClockwise(newFace);

            edge2->setNextClockwise(edge, edgeSignal);
            edge2->setPreviousClockwise(edge1, edge1Signal);
        }else{
            edge2->setCounterClockwise(newFace);

            edge2->setNextCounterClockwise(edge, edgeSignal);;
            edge2->setPreviousCounterClockwise(edge1, edge1Signal);
        }

        if(edgeSignal){
            edge->setClockwise(newFace);

            edge->setNextClockwise(edge1, edge1Signal);
            edge->setPreviousClockwise(edge2, edge2Signal);
        }else{
            edge->setCounterClockwise(newFace);

            edge->setNextCounterClockwise(edge1, edge1Signal);
            edge->setPreviousCounterClockwise(edge2, edge2Signal);
        }

//
//            std::cout <<" \t(" << edgeSignal << ")E" << edge->getID() <<" (" << edge->getStart()->getID() <<", " << edge->getEnd()->getID() <<")" <<std::endl;
//            if(edge->getClockwise()) std::cout <<" \t\tFACEcw: " << edge->getClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEcw: -"  <<std::endl;
//            if(edge->getCounterClockwise()) std::cout <<" \t\tFACEccw: " << edge->getCounterClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEccw: -"  <<std::endl;
//            if(edge->getNextClockwise()) std::cout <<" \t\tARESTAncw: (" << edge->getNextClockwiseSignal() << ")E" << edge->getNextClockwise()->getID() <<" (" << edge->getNextClockwise()->getStart()->getID() <<", " << edge->getNextClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAncw: -"  <<std::endl;
//            if(edge->getPreviousClockwise()) std::cout <<" \t\tARESTApcw: (" << edge->getPreviousClockwiseSignal() << ")E" << edge->getPreviousClockwise()->getID() <<" (" << edge->getPreviousClockwise()->getStart()->getID() <<", " << edge->getPreviousClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTApcw: -"  <<std::endl;
//            if(edge->getNextCounterClockwise()) std::cout <<" \t\tARESTAnccw: (" << edge->getNextCounterClockwiseSignal() << ")E" << edge->getNextCounterClockwise()->getID() <<" (" << edge->getNextCounterClockwise()->getStart()->getID() <<", " << edge->getNextCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAnccw: -"  <<std::endl;
//            if(edge->getPreviousCounterClockwise()) std::cout <<" \t\tARESTApccw: (" << edge->getPreviousCounterClockwiseSignal() << ")E" << edge->getPreviousCounterClockwise()->getID() <<" (" << edge->getPreviousCounterClockwise()->getStart()->getID() <<", " << edge->getPreviousCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTApccw: -"  <<std::endl;
//
//            std::cout <<" \t(" << edge1Signal << ")E" << edge1->getID() <<" (" << edge1->getStart()->getID() <<", " << edge1->getEnd()->getID() <<")" <<std::endl;
//            if(edge1->getClockwise()) std::cout <<" \t\tFACEcw: " << edge1->getClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEcw: -"  <<std::endl;
//            if(edge1->getCounterClockwise()) std::cout <<" \t\tFACEccw: " << edge1->getCounterClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEccw: -"  <<std::endl;
//            if(edge1->getNextClockwise()) std::cout <<" \t\tARESTAncw: (" << edge1->getNextClockwiseSignal() << ")E" << edge1->getNextClockwise()->getID() <<" (" << edge1->getNextClockwise()->getStart()->getID() <<", " << edge1->getNextClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAncw: -"  <<std::endl;
//            if(edge1->getPreviousClockwise()) std::cout <<" \t\tARESTApcw: (" << edge1->getPreviousClockwiseSignal() << ")E" << edge1->getPreviousClockwise()->getID() <<" (" << edge1->getPreviousClockwise()->getStart()->getID() <<", " << edge1->getPreviousClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTApcw: -"  <<std::endl;
//            if(edge1->getNextCounterClockwise()) std::cout <<" \t\tARESTAnccw: (" << edge1->getNextCounterClockwiseSignal() << ")E" << edge1->getNextCounterClockwise()->getID() <<" (" << edge1->getNextCounterClockwise()->getStart()->getID() <<", " << edge1->getNextCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAnccw: -"  <<std::endl;
//            if(edge1->getPreviousCounterClockwise()) std::cout <<" \t\tARESTApccw: (" << edge1->getPreviousCounterClockwiseSignal() << ")E" << edge1->getPreviousCounterClockwise()->getID() <<" (" << edge1->getPreviousCounterClockwise()->getStart()->getID() <<", " << edge1->getPreviousCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTApccw: -"  <<std::endl;
//
//            std::cout <<" \t(" << edge2Signal << ")E" << edge2->getID() <<" (" << edge2->getStart()->getID() <<", " << edge2->getEnd()->getID() <<")" <<std::endl;
//            if(edge2->getClockwise()) std::cout <<" \t\tFACEcw: " << edge2->getClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEcw: -"  <<std::endl;
//            if(edge2->getCounterClockwise())std::cout <<" \t\tFACEccw: " << edge2->getCounterClockwise()->getID()  <<std::endl;
//            else std::cout <<" \t\tFACEccw: -"  <<std::endl;
//            if(edge2->getNextClockwise()) std::cout <<" \t\tARESTAncw: (" << edge2->getNextClockwiseSignal() << ")E" << edge2->getNextClockwise()->getID() <<" (" << edge2->getNextClockwise()->getStart()->getID() <<", " << edge2->getNextClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAncw: -"  <<std::endl;
//            if(edge2->getPreviousClockwise()) std::cout <<" \t\tARESTApcw: (" << edge2->getPreviousClockwiseSignal() << ")E" << edge2->getPreviousClockwise()->getID() <<" (" << edge2->getPreviousClockwise()->getStart()->getID() <<", " << edge2->getPreviousClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTApcw: -"  <<std::endl;
//            if(edge2->getNextCounterClockwise()) std::cout <<" \t\tARESTAnccw: (" << edge2->getNextCounterClockwiseSignal() << ")E" << edge2->getNextCounterClockwise()->getID() <<" (" << edge2->getNextCounterClockwise()->getStart()->getID() <<", " << edge2->getNextCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            else std::cout <<" \t\tARESTAnpcw: -"  <<std::endl;
//            if(edge2->getPreviousCounterClockwise())std::cout <<" \t\tARESTApccw: (" << edge2->getPreviousCounterClockwiseSignal() << ")E" << edge2->getPreviousCounterClockwise()->getID() <<" (" << edge2->getPreviousCounterClockwise()->getStart()->getID() <<", " << edge2->getPreviousCounterClockwise()->getEnd()->getID() <<")" <<std::endl <<std::endl <<std::endl <<std::endl;
//            else std::cout <<" \t\tARESTApccw: -"  <<std::endl;
//
//            int nhe;
//            std::cin >> nhe;


    }

    _obj->removeFace(_f);
    //remove pq precisa deletar ja que criou outras no lugar.
    return result;
}

void AdvancingFront2D::fixEdges(Object *_obj, Face *_f){

//    std::cout <<"---------------------Triangulando face " << _f->getID() <<std::endl;

    //tem que triangularizar a face em questão

    //primeira coisa a se fazer: olhar se algum vertice é combinação linear de alguma aresta,
    //se for, tem que remover a aresta e criar duas novas
        //lembrar de modificar na face a aresta nova
        //lembrar de modificar anterior e posterior das arestas ligadas a aresta antiga
        //modificar também as arestas ligadas aos vertices
        //tomar cuidado para a direção continuar a mesma

    std::vector<Vertex *> verticesInThePlan = _f->getVerticesInThePlan();
    Edge *edge, *edge1, *edge2, *nextPrevEdge;
    bool edgeSignal, edge1Signal, edge2Signal, nextPrevEdgeSignal;
    Edge testEdge;
    Vertex *vertex;
    Face *face;
    for(unsigned int i = 0; i < verticesInThePlan.size(); i++){

        vertex = verticesInThePlan.at(i);
        if(vertex->isBoundary()) continue;

        edge = _f->getEdge();
        edgeSignal = _f->getEdgeSignal();
        do{

//            std::cout <<"--------Vendo se V" << vertex->getID() << " é paralelo a aresta Sinal:" << edgeSignal << " E" << edge->getID() << " na face " << _f->getID() <<std::endl;
            testEdge = Edge(-1, edge->getStart(), vertex);
            if(isParallel(*edge, testEdge)){
                vertex->setIsBoundary(true);
                edge1 = new Edge(edgeID++, edge->getStart(), vertex, true);
                edge1Signal = _obj->addEdge(&edge1);



                if((!edge1Signal) ||(edge1->getID() != edgeID -1)){
                    std::cout <<"!!achou uma aresta que ja existia" <<std::endl;
                }


                if(edge1Signal){
                    edge1Signal = edgeSignal;
                }else{
                    edge1Signal = !edgeSignal;
                }

                edge2 = new Edge(edgeID++, vertex, edge->getEnd(), true);
                edge2Signal = _obj->addEdge(&edge2);


                if((!edge2Signal) ||(edge2->getID() != edgeID -1)){
                    std::cout <<"!!achou uma aresta que ja existia" <<std::endl;
                }



                if(edge2Signal){
                    edge2Signal = edgeSignal;
                }else{
                    edge2Signal = !edgeSignal;
                }


                if(edgeSignal){
//                    std::cout <<"Setando aresta da face " << _f->getID() << "para aresta +" << edge1->getID() <<std::endl;

                    face = edge->getClockwise();
                    face->setEdge(edge1, edge1Signal);

                    face = edge->getCounterClockwise();
                    face->setEdge(edge1, !edge1Signal);

                    nextPrevEdge = edge->getPreviousClockwise();
                    nextPrevEdgeSignal = edge->getPreviousClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setNextClockwise(edge1, edge1Signal);
                    }else{
                        nextPrevEdge->setNextCounterClockwise(edge1, edge1Signal);
                    }

                    nextPrevEdge = edge->getNextCounterClockwise();
                    nextPrevEdgeSignal = edge->getNextCounterClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setPreviousClockwise(edge1, !edge1Signal);
                    }else{
                        nextPrevEdge->setPreviousCounterClockwise(edge1, !edge1Signal);
                    }

                    if(edge1Signal){
                        edge1->setPreviousClockwise(edge->getPreviousClockwise(), edge->getPreviousClockwiseSignal());
                        edge1->setNextCounterClockwise(edge->getNextCounterClockwise(), edge->getNextCounterClockwiseSignal());
                        edge1->setPreviousCounterClockwise(edge2, !edge2Signal);
                        edge1->setNextClockwise(edge2, edge2Signal);

                        edge1->setClockwise(edge->getClockwise());
                        edge1->setCounterClockwise(edge->getCounterClockwise());
                    }else{
                        edge1->setPreviousCounterClockwise(edge->getPreviousClockwise(), edge->getPreviousClockwiseSignal());
                        edge1->setNextClockwise(edge->getNextCounterClockwise(), edge->getNextCounterClockwiseSignal());
                        edge1->setPreviousClockwise(edge2, !edge2Signal);
                        edge1->setNextCounterClockwise(edge2, edge2Signal);

                        edge1->setClockwise(edge->getCounterClockwise());
                        edge1->setCounterClockwise(edge->getClockwise());
                    }

                    nextPrevEdge = edge->getNextClockwise();
                    nextPrevEdgeSignal = edge->getNextClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setPreviousClockwise(edge2, edge2Signal);
                    }else{
                        nextPrevEdge->setPreviousCounterClockwise(edge2, edge2Signal);
                    }

                    nextPrevEdge = edge->getPreviousCounterClockwise();
                    nextPrevEdgeSignal = edge->getPreviousCounterClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setNextClockwise(edge2, !edge2Signal);
                    }else{
                        nextPrevEdge->setNextCounterClockwise(edge2, !edge2Signal);
                    }

                    if(edge2Signal){
                        edge2->setNextClockwise(edge->getNextClockwise(), edge->getNextClockwiseSignal());
                        edge2->setPreviousCounterClockwise(edge->getPreviousCounterClockwise(), edge->getPreviousCounterClockwiseSignal());
                        edge2->setNextCounterClockwise(edge1, !edge1Signal);
                        edge2->setPreviousClockwise(edge1, edge1Signal);

                        edge2->setClockwise(edge->getClockwise());
                        edge2->setCounterClockwise(edge->getCounterClockwise());
                    }else{
                        edge2->setNextCounterClockwise(edge->getNextClockwise(), edge->getNextClockwiseSignal());
                        edge2->setPreviousClockwise(edge->getPreviousCounterClockwise(), edge->getPreviousCounterClockwiseSignal());
                        edge2->setNextClockwise(edge1, !edge1Signal);
                        edge2->setPreviousCounterClockwise(edge1, edge1Signal);

                        edge2->setClockwise(edge->getCounterClockwise());
                        edge2->setCounterClockwise(edge->getClockwise());
                    }

                    edge->getStart()->setEdge(edge1, edge1Signal);
                    vertex->setEdge(edge2, edge2Signal);
                    edge->getEnd()->setEdge(edge2, !edge2Signal);
                }else{
//                    std::cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!\nChecar se dar realmente certo! "<<"\nSetando aresta da face " << _f->getID() << "para aresta - " << edge1->getID() <<std::endl;
//                    int nhe;
//                    std::cin >> nhe;

                    face = edge->getClockwise();
                    face->setEdge(edge1, !edge1Signal);

                    face = edge->getCounterClockwise();
                    face->setEdge(edge1, edge1Signal);

                    nextPrevEdge = edge->getPreviousClockwise();
                    nextPrevEdgeSignal = edge->getPreviousClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setNextClockwise(edge1, !edge1Signal);
                    }else{
                        nextPrevEdge->setNextCounterClockwise(edge1, !edge1Signal);
                    }

                    nextPrevEdge = edge->getNextCounterClockwise();
                    nextPrevEdgeSignal = edge->getNextCounterClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setPreviousClockwise(edge1, edge1Signal);
                    }else{
                        nextPrevEdge->setPreviousCounterClockwise(edge1, edge1Signal);
                    }

                    if(!edge1Signal){
                        edge1->setPreviousClockwise(edge->getPreviousClockwise(), edge->getPreviousClockwiseSignal());
                        edge1->setNextCounterClockwise(edge->getNextCounterClockwise(), edge->getNextCounterClockwiseSignal());
                        edge1->setPreviousCounterClockwise(edge2, edge2Signal);
                        edge1->setNextClockwise(edge2, !edge2Signal);

                        edge1->setClockwise(edge->getClockwise());
                        edge1->setCounterClockwise(edge->getCounterClockwise());
                    }else{
                        edge1->setPreviousCounterClockwise(edge->getPreviousClockwise(), edge->getPreviousClockwiseSignal());
                        edge1->setNextClockwise(edge->getNextCounterClockwise(), edge->getNextCounterClockwiseSignal());
                        edge1->setPreviousClockwise(edge2, edge2Signal);
                        edge1->setNextCounterClockwise(edge2, !edge2Signal);

                        edge1->setClockwise(edge->getCounterClockwise());
                        edge1->setCounterClockwise(edge->getClockwise());
                    }


                    nextPrevEdge = edge->getNextClockwise();
                    nextPrevEdgeSignal = edge->getNextClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setPreviousClockwise(edge2, !edge2Signal);
                    }else{
                        nextPrevEdge->setPreviousCounterClockwise(edge2, !edge2Signal);
                    }

                    nextPrevEdge = edge->getPreviousCounterClockwise();
                    nextPrevEdgeSignal = edge->getPreviousCounterClockwiseSignal();
                    if(nextPrevEdgeSignal){
                        nextPrevEdge->setNextClockwise(edge2, edge2Signal);
                    }else{
                        nextPrevEdge->setNextCounterClockwise(edge2, edge2Signal);
                    }

                    if(!edge2Signal){
                        edge2->setNextClockwise(edge->getNextClockwise(), edge->getNextClockwiseSignal());
                        edge2->setPreviousCounterClockwise(edge->getPreviousCounterClockwise(), edge->getPreviousCounterClockwiseSignal());
                        edge2->setNextCounterClockwise(edge1, edge1Signal);
                        edge2->setPreviousClockwise(edge1, !edge1Signal);

                        edge2->setClockwise(edge->getClockwise());
                        edge2->setCounterClockwise(edge->getCounterClockwise());
                    }else{
                        edge2->setNextCounterClockwise(edge->getNextClockwise(), edge->getNextClockwiseSignal());
                        edge2->setPreviousClockwise(edge->getPreviousCounterClockwise(), edge->getPreviousCounterClockwiseSignal());
                        edge2->setNextClockwise(edge1, edge1Signal);
                        edge2->setPreviousCounterClockwise(edge1, !edge1Signal);

                        edge2->setClockwise(edge->getCounterClockwise());
                        edge2->setCounterClockwise(edge->getClockwise());
                    }

                    edge->getStart()->setEdge(edge1, !edge1Signal);
                    vertex->setEdge(edge2, !edge2Signal);
                    edge->getEnd()->setEdge(edge2, edge2Signal);
                }


//            std::cout <<"\n\n------ TROCANDO  (" << edgeSignal << ")E" << edge->getID()  <<" (" << edge->getStart()->getID() <<", " << edge->getEnd()->getID() <<")" <<std::endl;
//
//            std::cout <<" \t(" << edge1Signal << ")E" << edge1->getID() <<" (" << edge1->getStart()->getID() <<", " << edge1->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tFACEcw: " << edge1->getClockwise()->getID()  <<std::endl;
//            std::cout <<" \t\tFACEccw: " << edge1->getCounterClockwise()->getID()  <<std::endl;
//            std::cout <<" \t\tARESTAncw: (" << edge1->getNextClockwiseSignal() << ")E" << edge1->getNextClockwise()->getID() <<" (" << edge1->getNextClockwise()->getStart()->getID() <<", " << edge1->getNextClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTApcw: (" << edge1->getPreviousClockwiseSignal() << ")E" << edge1->getPreviousClockwise()->getID() <<" (" << edge1->getPreviousClockwise()->getStart()->getID() <<", " << edge1->getPreviousClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTAnccw: (" << edge1->getNextCounterClockwiseSignal() << ")E" << edge1->getNextCounterClockwise()->getID() <<" (" << edge1->getNextCounterClockwise()->getStart()->getID() <<", " << edge1->getNextCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTApccw: (" << edge1->getPreviousCounterClockwiseSignal() << ")E" << edge1->getPreviousCounterClockwise()->getID() <<" (" << edge1->getPreviousCounterClockwise()->getStart()->getID() <<", " << edge1->getPreviousCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//
//            std::cout <<" \t(" << edge2Signal << ")E" << edge2->getID() <<" (" << edge2->getStart()->getID() <<", " << edge2->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tFACEcw: " << edge2->getClockwise()->getID()  <<std::endl;
//            std::cout <<" \t\tFACEccw: " << edge2->getCounterClockwise()->getID()  <<std::endl;
//            std::cout <<" \t\tARESTAncw: (" << edge2->getNextClockwiseSignal() << ")E" << edge2->getNextClockwise()->getID() <<" (" << edge2->getNextClockwise()->getStart()->getID() <<", " << edge2->getNextClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTApcw: (" << edge2->getPreviousClockwiseSignal() << ")E" << edge2->getPreviousClockwise()->getID() <<" (" << edge2->getPreviousClockwise()->getStart()->getID() <<", " << edge2->getPreviousClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTAnccw: (" << edge2->getNextCounterClockwiseSignal() << ")E" << edge2->getNextCounterClockwise()->getID() <<" (" << edge2->getNextCounterClockwise()->getStart()->getID() <<", " << edge2->getNextCounterClockwise()->getEnd()->getID() <<")" <<std::endl;
//            std::cout <<" \t\tARESTApccw: (" << edge2->getPreviousCounterClockwiseSignal() << ")E" << edge2->getPreviousCounterClockwise()->getID() <<" (" << edge2->getPreviousCounterClockwise()->getStart()->getID() <<", " << edge2->getPreviousCounterClockwise()->getEnd()->getID() <<")" <<std::endl <<std::endl <<std::endl <<std::endl;

                _obj->removeEdge(edge);
                break;
            }



            if(edgeSignal){
                edgeSignal = edge->getNextClockwiseSignal();
                edge = edge->getNextClockwise();
            }else{
                edgeSignal = edge->getNextCounterClockwiseSignal();
                edge = edge->getNextCounterClockwise();
            }
        }while (edge != _f->getEdge());
    }
}
